package com.kun.service.service.impl;

import com.kun.service.service.ITaskHistory;
import com.kun.utils.SecurityUtils;
import com.kun.vo.InstanceHistoryVo;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TaskHistoryImpl implements ITaskHistory {

    private final HistoryService historyService;
    private final RepositoryService repositoryService;

    public TaskHistoryImpl(HistoryService historyService, RepositoryService repositoryService) {
        this.historyService = historyService;
        this.repositoryService = repositoryService;
    }

    /**
     * 高亮显示已执行的节点，需要高亮的线
     */
    @Override
    public List<InstanceHistoryVo> highlightProcessHistory(String processInstanceId) {
        // 查询流程实例
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                // 根据流程实例ID查询
                .processInstanceId(processInstanceId)
                // 唯一
                .singleResult();
        // 获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        // 因为我们这里只定义了一个Process 所以获取集合中的第一个即可
        Process process = bpmnModel.getProcesses().get(0);
        //获取所有的FlowElement信息
        ArrayList<FlowElement> flowElements = (ArrayList<FlowElement>) process.getFlowElements();

        //获取流程实例 历史节点(全部)
        Map<String, HistoricActivityInstance> collect = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).list().stream()
                .collect(Collectors.toMap(HistoricActivityInstance::getActivityId, Function.identity()));
        // 查询执行人是我自己的，历史任务
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).taskAssignee(SecurityUtils.getUsername()).list();

        boolean flag = false;
        ArrayList<InstanceHistoryVo> instanceHistories = new ArrayList<>();
        // 执行过的（灰色），我执行的，当前执行的
        for (FlowElement flowElement : flowElements) {
            // 排除起始节点和结束节点
            if (flowElement instanceof StartEvent || flowElement instanceof EndEvent) {
                continue;
            }
            String id = flowElement.getId();
            String name = flowElement.getName();
            if (flowElement instanceof SequenceFlow) {
                String sourceRef = ((SequenceFlow) flowElement).getSourceRef();
                HistoricActivityInstance historicActivityInstance = list.stream().filter(taskInstance ->
                        taskInstance.getActivityId().equals(sourceRef)).findFirst().orElse(null);
                // 表示是我执行的并且已经执行过
                if (historicActivityInstance != null && historicActivityInstance.getEndTime() != null) {
                    InstanceHistoryVo e = new InstanceHistoryVo(id, name, 0, true, 0);
                    instanceHistories.add(e);
                }
                continue;
            }
            HistoricActivityInstance activiti = collect.get(flowElement.getId());
            // 第一个没有结束时间的是正在执行的
            int isExecuted = 0;
            if (activiti.getEndTime() == null) {
                isExecuted = flag ? 1 : 2;
                flag = true;
            }
            InstanceHistoryVo e = new InstanceHistoryVo(id, name, isExecuted,
                    Objects.equals(activiti.getAssignee(), SecurityUtils.getUsername()), 1);
            instanceHistories.add(e);
        }
        return instanceHistories;
    }
}
